#from numpy import *
import numpy as np

'''
初窥NumPy对象：数组
NumPy中的基本对象是同类型的多维数组（homogeneous multidimensional array），
这和C++中的数组是一致的，例如字符型和数值型就不可共存于同一个数组中。
'''

a = np.arange(20)
print("")
print(a)
print("")
#判断类型type
print(type(a))

'''
通过函数"reshape"，我们可以重新构造一下这个数组，例如，我们可以构造一个4*5的二维数组，其中"reshape"的参数表示各维度的大小，且按各维顺序排列（两维时就是按行排列，这和R中按列是不同的）
'''
print("")
print("通过函数'reshape'，我们可以重新构造一下这个数组，例如，我们可以构造一个4*5的二维数组，其中'reshape'的参数表示各维度的大小，且按各维顺序排列（两维时就是按行排列，这和R中按列是不同的）")
b = a.reshape(4, 5)
print("")
print(b)

print("构造更高维的也没问题 : a.reshape(2, 2, 5)")
c = a.reshape(2, 2, 5)
print(c)
print("")
print("查询维度 : c.ndim")
print(c.ndim)
print("")
print("查看各维度的大小 : c.shape")
print(c.shape)
print("")
print("查看全部的元素个数 : c.size")
print(c.size)
print("")
print("可查看元素类型: c.dtype")
print(c.dtype)

'''
三、创建数组

数组的创建可通过转换列表实现，高维数组可通过转换嵌套列表实现
'''
print("")
print("嵌套列表转换数据：")
raw = [0, 1, 2, 3, 4]
d = np.array(raw)
print(d)

print("")
raw = [[0,1,2,3,4], [5,6,7,8,9]]
e = np.array(raw)
print(e)

print("")
print("一些特殊的数组有特别定制的命令生成，如4*5的全零矩阵：")
d = (4,5)
print(np.zeros(d))

print("")
print("默认生成的类型是浮点型，可以通过指定类型改为整型")
d = (4,5)
print(np.ones(d, dtype=int))
print("")
print("[0, 1)区间的随机数数组:")
print(np.random.rand(5))


'''
四、数组操作

简单的四则运算已经重载过了，全部的'+'，'-'，'*'，'/'运算都是基于全部的数组元素的，以加法为例：
'''
print("")
print("数组加法")
a = np.array([[1.0, 2], [2, 4]])

print("a:")
print(a)

b = np.array([[3.2, 1.5], [2.5, 4]])
print("b:")
print(b)
print("a + b:")
print(a+b)

'''
这里可以发现，a中虽然仅有一个与元素是浮点数，其余均为整数，
在处理中Python会自动将整数转换为浮点数（因为数组是同质的），
并且，两个二维数组相加要求各维度大小相同。当然，NumPy里这些运算符也可以对标量和数组操作，
结果是数组的全部元素对应这个标量进行运算，还是一个数组：
'''
print("")
print("3 * a:")
print(3 * a)
print("b + 1.8:")
print(b + 1.8)
print("")

print("类似C++，'+='、'-='、'*='、'/='操作符在NumPy中同样支持：")
print("a/=2:")
a /= 2
print(a)

print("开根号求指数也很容易：")
print("a:")
print(a)
print("np.exp(a):")
print(np.exp(a))
print("np.sqrt(a):")
print(np.sqrt(a))
print("np.square(a)")
print(np.square(a))
print("np.power(a, 3)")
print(np.power(a, 3))

print('''


需要知道二维数组的最大最小值怎么办？
想计算全部元素的和、按行求和、按列求和怎么办？
for循环吗？不，NumPy的ndarray类已经做好函数了：

''')

a=np.arange(20).reshape(4, 5)
print("a:")
print(a)
print("sum of all elements in a:" + str(a.sum()))
print("maximum element in a: " + str(a.max()))
print("minimum element in a: " + str(a.min()))
print("maxumun element in each row of a: " + str(a.max(axis=1)))
print("minimum element each column of a: " + str(a.min(axis=0)))

print('''

科学计算中大量使用到矩阵运算，
除了数组，NumPy同时提供了矩阵对象（matrix）。
矩阵对象和数组的主要有两点差别：
一是矩阵是二维的，而数组的可以是任意正整数维；
二是矩阵的'*'操作符进行的是矩阵乘法，乘号左侧的矩阵列和乘号右侧的矩阵行要相等，
而在数组中'*'操作符进行的是每一元素的对应相乘，乘号两侧的数组每一维大小需要一致。
数组可以通过asmatrix或者mat转换为矩阵，或者直接生成也可以：

''')
a = np.arange(20).reshape(4, 5)
a = np.asmatrix(a)
print(type(a))
b = np.matrix('1.0 2.0; 3.0 4.0')
print(type(b))

print('''

再来看一下矩阵的乘法，这使用arange生成另一个矩阵b，
arange函数还可以通过arange(起始，终止，步长)的方式调用生成等差数列，
注意含头不含尾。
''')
b = np.arange(2, 45, 3).reshape(5, 3)
b = np.mat(b)
print(b)

print('''

有人要问了，arange指定的是步长，如果想指定生成的一维数组的长度怎么办？
好办，"linspace"就可以做到：
np.linspace(0, 2, 9)
''')
print(np.linspace(0, 2, 9))

print('''

回到我们的问题，矩阵a和b做矩阵乘法：
''')
print("matrix a:")
print(a)
print("")
print("matrix b:")
print(b)
print("")
print("c = a * b:")
c = a * b
print(c)